#ifndef __COMLOG_H_
#define __COMLOG_H_

#include "stdio.h"
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

#ifdef __cplusplus
extern "C"
{
#endif
/*设置是否使能打印函数*/
#define COMLOG_ENABLE_PRINT 0

#if COMLOG_ENABLE_PRINT == 1
#define COMLOG_PRINT printf
#else
#define COMLOG_PRINT
#endif

typedef enum eComLogDebugLevel_t
{
   COMLOG_NONE = 0,
   COMLOG_FATAL,
   COMLOG_ALARM,
   COMLOG_ERROR,
   COMLOG_WARN,
   COMLOG_INFO,
   COMLOG_DEBUG,
   COMLOG_MAX

}eComLogDebugLevel;

/*用户注册钩子接口，可以获取打印字符进行保存等其它操作*/
typedef void(*LogHook)(char *log_str);

/*处理打印的临时缓冲区大小*/
#define LOG_TEMP_BUF_SIZE (2048)

extern LogHook sHook;

extern eComLogDebugLevel MAX_DEBUG_LEVEL;
/*
 * brief : 设置打印等级
 * level : 打印等级
 */
void ComLogSetLevel(eComLogDebugLevel level);

/*
 * brief : 设置钩子函数
 * hook : 钩子函数
 */
void ComLogSetHook(LogHook hook);

/*非对外接口*/
void ComLogSendToHook(char *str);

static void ComLogHexDump(eComLogDebugLevel level, char *data, int datalen)
{
   char tempbuf[LOG_TEMP_BUF_SIZE] = {0};
   if(level > MAX_DEBUG_LEVEL)
      return ;
   int i = 0, c = 0;
   while (datalen > 0)
    {
        memset(tempbuf, 0, sizeof(tempbuf));
        sprintf(tempbuf+strlen(tempbuf),"%08X: ", data);
        for (i = 0;  i < 16;  i++) 
        {
            if (i < datalen) 
            {
                sprintf(tempbuf+strlen(tempbuf),"%02X ", data[i] & 0xFF);
            }
            else 
            {
                sprintf(tempbuf+strlen(tempbuf),"%s", "   ");
            }
            if (i == 7) 
            {
                sprintf(tempbuf+strlen(tempbuf),"%s", " ");
            }
           
        }
        sprintf(tempbuf+strlen(tempbuf),"%s", " |");
        for (i = 0;  i < 16;  i++) {
            if (i < datalen) 
            {
                c = data[i] & 0xFF;
                if ((c < 0x20) || (c >= 0x7F)) 
                   c = '.';
            } else 
            {
                c = ' ';
            }
            sprintf(tempbuf+strlen(tempbuf),"%c", c);
        }
        sprintf(tempbuf+strlen(tempbuf),"%s", "|\n");
        ComLogSendToHook(tempbuf);
        COMLOG_PRINT("%s", tempbuf);
        datalen -= 16;
        data += 16;
    }
    COMLOG_PRINT("\n");
    COMLOG_PRINT("\n");
}


static void COMLOG_LOG(const char *tag, const char *file, const char *func, int line, eComLogDebugLevel level, char *fmt, ...) 
{
     char tempbuf[LOG_TEMP_BUF_SIZE] = {0};
     va_list vl;
     va_start(vl, fmt);
     if(level <= MAX_DEBUG_LEVEL){  
        struct tm temptemp;
        char timestr[50] = {0};
        time_t timestamp = time(NULL); 
        localtime_r(&timestamp, &temptemp);
        asctime_r(&temptemp,timestr);
        memset(timestr+strlen(timestr)-1, 0, 2);
        snprintf(tempbuf, sizeof(tempbuf), "[%s][%s][%d][%s][%s]", file, func, line,timestr,tag);
        //vprintf(fmt,  vl); 
        vsnprintf(tempbuf + strlen(tempbuf), sizeof(tempbuf) - strlen(tempbuf), fmt, vl);
        COMLOG_PRINT("%s", tempbuf); 
        ComLogSendToHook(tempbuf);
      }  
     va_end(vl);
}


    
#define FILENAME(x) strrchr(x,'/')?strrchr(x,'/')+1:x



//字符串打印
#define COMLOG_FATAL_LOG(fmt, ...) COMLOG_LOG("Fatal", FILENAME(__FILE__), __FUNCTION__, __LINE__, COMLOG_FATAL, fmt, ##__VA_ARGS__)
#define COMLOG_ALARM_LOG(fmt, ...) COMLOG_LOG("Alarm", FILENAME(__FILE__), __FUNCTION__, __LINE__, COMLOG_ALARM, fmt, ##__VA_ARGS__)
#define COMLOG_ERROR_LOG(fmt, ...) COMLOG_LOG("Error", FILENAME(__FILE__), __FUNCTION__, __LINE__, COMLOG_ERROR, fmt, ##__VA_ARGS__)
#define COMLOG_WARN_LOG(fmt, ...)  COMLOG_LOG("Warn",  FILENAME(__FILE__), __FUNCTION__, __LINE__, COMLOG_WARN,  fmt, ##__VA_ARGS__)
#define COMLOG_INFO_LOG(fmt, ...)  COMLOG_LOG("Info",  FILENAME(__FILE__), __FUNCTION__, __LINE__, COMLOG_INFO,  fmt, ##__VA_ARGS__)
#define COMLOG_DEBUG_LOG(fmt, ...) COMLOG_LOG("Debug", FILENAME(__FILE__), __FUNCTION__, __LINE__, COMLOG_DEBUG, fmt, ##__VA_ARGS__)

//hexdump打印
#define  COMLOG_FATAL_HEXDUMP(data, len) ComLogHexDump(COMLOG_FATAL, data, len)
#define  COMLOG_ALARM_HEXDUMP(data, len) ComLogHexDump(COMLOG_ALARM, data, len)
#define  COMLOG_ERROR_HEXDUMP(data, len) ComLogHexDump(COMLOG_ERROR, data, len)
#define  COMLOG_WARN_HEXDUMP(data, len)  ComLogHexDump(COMLOG_WARN,  data, len)
#define  COMLOG_INFO_HEXDUMP(data, len)  ComLogHexDump(COMLOG_INFO,  data, len)
#define  COMLOG_DEBUG_HEXDUMP(data, len) ComLogHexDump(COMLOG_DEBUG, data, len)

//常用linux下颜色标号,需要标记颜色的可用：COMLOG_FATAL_LOG(COMLOG_L_BLACK"Hello,World"COMLOG_NONE);
#define COMLOG_NONE                 "\e[0m"
#define COMLOG_BLACK                "\e[0;30m"
#define COMLOG_L_BLACK              "\e[1;30m"
#define COMLOG_RED                  "\e[0;31m"
#define COMLOG_L_RED                "\e[1;31m"
#define COMLOG_GREEN                "\e[0;32m"
#define COMLOG_L_GREEN              "\e[1;32m"
#define COMLOG_BROWN                "\e[0;33m"
#define COMLOG_YELLOW               "\e[1;33m"
#define COMLOG_BLUE                 "\e[0;34m"
#define COMLOG_L_BLUE               "\e[1;34m"
#define COMLOG_PURPLE               "\e[0;35m"
#define COMLOG_L_PURPLE             "\e[1;35m"
#define COMLOG_CYAN                 "\e[0;36m"
#define COMLOG_L_CYAN               "\e[1;36m"
#define COMLOG_GRAY                 "\e[0;37m"
#define COMLOG_WHITE                "\e[1;37m"
#define COMLOG_BOLD                 "\e[1m"
#define COMLOG_UNDERLINE            "\e[4m"
#define COMLOG_BLINK                "\e[5m"
#define COMLOG_REVERSE              "\e[7m"
#define COMLOG_HIDE                 "\e[8m"
#define COMLOG_CLEAR                "\e[2J"

#ifdef __cplusplus
}
#endif
#endif